import json
import sys
import requests
from core.tools.func_utils import parse_qsl

from requests_pkcs12 import request as pkcs12_request
import requests_pkcs12
import contextlib
import OpenSSL
import os
import tempfile


class CustomRequests(object):
    base_url = None
    _http = requests.Session()

    def get(self, url, **kwargs):
        return self._request(
            method='get',
            url_or_endpoint=url,
            **kwargs
        )

    def post(self, url, **kwargs):
        return self._request(
            method='post',
            url_or_endpoint=url,
            **kwargs
        )

    def _request(self, method, url_or_endpoint, **kwargs):
        if not url_or_endpoint.startswith(('http://', 'https://')):
            api_base_url = kwargs.pop('api_base_url', self.base_url)
            url = '{base}{endpoint}'.format(
                base=api_base_url,
                endpoint=url_or_endpoint
            )
        else:
            url = url_or_endpoint
        if not kwargs.get("verify"):
            kwargs["verify"] = False
        res = self._http.request(
            method=method,
            url=url,
            **kwargs
        )
        content = res.content.decode('utf-8', 'ignore')
        try:
            result = json.loads(content)
            return result
        except (TypeError, ValueError):
            try:
                params = parse_qsl(content, keep_blank_values=True)
                result = {key[0]: key[1] for key in params}
                return result
            except (TypeError, ValueError):
                raise TypeError('Can not decode response as JSON')

    def delete_none(self, **params):
        data = dict()
        for k, v in params.items():
            if v is not None:
                data[k] = v
        return data

    def join_and(self, query):
        if hasattr(query, "items"):
            query = query.items()
        else:
            # It's a bother at times that strings and string-like objects are
            # sequences.
            try:
                # non-sequence items should not work with len()
                # non-empty strings will fail this
                if len(query) and not isinstance(query[0], tuple):
                    raise TypeError
                    # Zero-length sequences of all types will get here and succeed,
                    # but that's a minor nit.  Since the original implementation
                    # allowed empty dicts that type of behavior probably should be
                    # preserved for consistency
            except TypeError:
                ty, va, tb = sys.exc_info()
                raise TypeError("not a valid non-string sequence "
                                "or mapping object").with_traceback(tb)
        l = []
        for k, v in query:
            l.append(k + '=' + v)
        return '&'.join(l)


class SSLRequests(object):
    base_url = None

    def get(self, url, **kwargs):
        return self._request(
            'get',
            url,
            **kwargs
        )

    def post(self, url, **kwargs):
        return self._request(
            'post',
            url,
            **kwargs
        )

    def _request(self, method, url_or_endpoint, **kwargs):
        if not url_or_endpoint.startswith(('http://', 'https://')):
            api_base_url = kwargs.pop('api_base_url', self.base_url)
            url = '{base}{endpoint}'.format(
                base=api_base_url,
                endpoint=url_or_endpoint
            )
        else:
            url = url_or_endpoint
        res = pkcs12_request(
            method,
            url,
            **kwargs
        )
        print(res)
        content = res.content.decode('utf-8', 'ignore')
        try:
            result = json.loads(content)
            return result
        except (TypeError, ValueError):
            try:
                params = parse_qsl(content, keep_blank_values=True)
                result = {key[0]: key[1] for key in params}
                return result
            except (TypeError, ValueError):
                raise TypeError('Can not decode response as JSON')
